<template>
  <view class="container">
    <slot name="topBarSlot">
      <view class="top-panel" v-if="showTopBar">
        <!-- 搜索栏 -->
        <view class="top-wrapper">
          <view class="search-bar">
            <image
              src="https://jhl-pay.oss-cn-shenzhen.aliyuncs.com/agent/ico-input-search.png"
            />
            <slot name="barLeftSlot">
              <input
                v-model="keyword"
                :placeholder="placeholder"
                @confirm="$emit('search', keyword)"
                @input="$emit('input', keyword)"
                confirm-type="search"
                placeholderStyle="color:#999999;"
              />
            </slot>
          </view>
          <slot name="barRightSlot">
            <view
              class="filter-text"
              @click="filterEvent"
              v-if="showFilterButton"
              >筛选</view
            >
          </slot>
        </view>
        <!-- 统计 -->
        <slot name="summarySlot">
          <template v-if="showSummary && !isEmpty(summaryData)">
            <view class="summary" v-if="Array.isArray(summaryData)">
              <text v-for="(item, index) in summaryData" :key="index">
                {{ item.label }}：{{ item.value }}{{ " " }}
              </text>
            </view>
            <view class="summary" v-else-if="isObject(summaryData)">
              {{ summaryData.label || "" }}：{{ summaryData.value }}
            </view>
            <view class="summary" v-else>
              <rich-text :nodes="summaryData" />
            </view>
          </template>
        </slot>
      </view>
    </slot>

    <!-- 筛选面板 -->
    <slot name="filterSlot">
      <FilterPanel
        :show="showFilterPanel"
        @close="showFilterPanel = false"
        @reset="filterReset"
        @confirm="filterConfirm"
      >
        <slot name="filterItemSlot"></slot>
      </FilterPanel>
    </slot>

    <!-- 列表 -->
    <scroll-view
      class="list-wrapper"
      scroll-y="true"
      :refresher-enabled="true"
      :refresher-triggered="isRefreshing"
      @refresherrefresh="$emit('refresh')"
      @scrolltolower="$emit('loadMore')"
      v-if="list.length > 0"
    >
      <view
        class="card-wrapper"
        :style="itemStyle"
        v-for="(item, index) in list"
        :key="index"
        @click="$emit('onItemClick', item)"
      >
        <slot name="itemSlot" :item="item"></slot>
      </view>
    </scroll-view>

    <!-- 没有数据 -->
    <EmptyData v-else class="empty-data" />
  </view>
</template>

<script>
export default {
  data() {
    return {
      listHeight: 0, // 列表高度
    };
  },
  beforeUpdate() {
    // 只获取一次即可，避免资源浪费
    if (!this.listHeight) {
      uni
        .createSelectorQuery()
        .in(this)
        .select(".list-wrapper")
        .boundingClientRect((data) => {
          if (data) {
            this.listHeight = data.height;
            this.$emit("updateHeight", this.listHeight);
          }
        })
        .exec();
    }
  },
};
</script>

<script setup name="BaseList">
import { showToast } from "@/utils/toast";
import { isObject, isEmpty } from "lodash";
import { ref } from "vue";
import FilterPanel from "./filter-panel";
import EmptyData from "./empty-data";

const props = defineProps({
  // 是否显示顶部搜索栏区域
  showTopBar: {
    type: Boolean,
    default: true,
  },
  // 输入框提示文字
  placeholder: String,
  // 是否显示统计栏区域
  showSummary: {
    type: Boolean,
    default: true,
  },
  // 统计栏数据，Object格式为{label:xxx,value:xxx}
  summaryData: [Array, Object, String],
  // 列表数据
  list: Array,
  // 列表项样式
  itemStyle: String,
  // 是否正在刷新
  isRefreshing: Boolean,
  // 是否显示筛选按钮
  showFilterButton: {
    type: Boolean,
    default: true,
  },
  // 是否可筛选，临时使用，用于暂无筛选功能的页面进行提示
  isFilter: {
    type: Boolean,
    default: true,
  },
});

const emits = defineEmits([
  "refresh",
  "loadMore",
  "search",
  "onFilter",
  "filterReset",
  "filterConfirm",
  "onItemClick",
]);

// 输入框内容
let keyword = ref(null);

// 是否显示筛选面板
let showFilterPanel = ref(false);

// 筛选事件
function filterEvent() {
  if (props.isFilter) {
    showFilterPanel.value = true;
  } else {
    showToast("功能开发中", "none");
  }
  emits("onFilter");
}

// 重置筛选项
function filterReset() {
  emits("filterReset");
}

// 确认筛选
function filterConfirm() {
  emits("filterConfirm");
}
</script>

<style lang="scss" scoped>
.container {
  height: 100%;
  background: #f2f2f2;
  display: flex;
  flex-direction: column;

  // 搜索栏
  .top-panel {
    padding: 20rpx 30rpx;
    box-sizing: border-box;
    background: #ffffff;
    .top-wrapper {
      display: flex;
      align-items: center;
      font-size: 26rpx;
      font-weight: 400;
      color: #333333;
      .search-bar {
        flex: 1;
        display: flex;
        align-items: center;
        box-sizing: border-box;
        padding: 11rpx 27rpx 12rpx;
        height: 58rpx;
        background: #f2f2f2;
        border-radius: 30rpx;

        image {
          width: 36rpx;
          height: 35rpx;
          margin-right: 10rpx;
        }
        input {
          flex: 1;
        }
      }
      .filter-text {
        margin-left: 20rpx;
      }
    }

    .summary {
      font-size: 22rpx;
      font-weight: 400;
      color: #333333;
      margin-top: 20rpx;
    }
  }

  // 列表
  .list-wrapper {
    position: relative;
    flex: 1;
    padding: 20rpx 0;
    box-sizing: border-box;
    overflow: hidden;
    .card-wrapper {
      background: #ffffff;
      border-radius: 20rpx;
      padding: 20rpx;
      margin: 0 30rpx 20rpx;
    }
  }

  // 暂无数据
  .empty-data {
    width: 100%;
    height: 100%;
  }
}
</style>
